﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FytSoa.Common.Utils;
using FytSoa.Domain.Core.Result;
using FytSoa.Generator.Utils;
using FytSoa.Sugar;
using SqlSugar;

namespace FytSoa.Generator
{
    public class GeneratorService:SugarRepository<GeneratorService>
    {
        /// <summary>
        /// 目录分隔符
        /// windows "\" OSX and Linux  "/"
        /// </summary>
        private static string _directorySeparatorChar = Path.DirectorySeparatorChar.ToString();
        
        /// <summary>
        /// 连接数据库，并返回当前连接下所有表名字
        /// </summary>
        /// <returns></returns>
        public ApiResult<List<DbTableInfo>> InitConnection()
        {
            var result = JResult<List<DbTableInfo>>.Success();
            try
            {
                result.Data=base.Context.DbMaintenance.GetTableInfoList();
                return result;
            }
            catch (Exception ex)
            {
                return JResult<List<DbTableInfo>>.Error(ex.Message);
            }
        }
        
        /// <summary>
        /// 生成代码
        /// </summary>
        /// <returns></returns>
        public ApiResult<string> CreateCode(GeneratorTableDto createModel)
        {
            var result = JResult<string>.Success();
            try
            {
                var basePath = AppContext.BaseDirectory;
                var path = basePath + @"Generator";
                FileUtils.CreateSuffic(path);
                var db = base.Context;
                //读取模板——实体
                var modelTemp = FileUtils.ReadFile(basePath + @"Template"+_directorySeparatorChar+"Model.txt");
                //读取模板——Dto
                var dtoTemp = FileUtils.ReadFile(basePath + @"Template"+_directorySeparatorChar+"Dto.txt");
                //读取模板——接口服务
                var iserviceTemp = FileUtils.ReadFile(basePath + @"Template"+_directorySeparatorChar+"IService.txt");
                //读取模板——服务实现
                var serviceTemp = FileUtils.ReadFile(basePath + @"Template"+_directorySeparatorChar+"Service.txt");
                //读取模板Tree——接口服务
                var iTreeServiceTemp = FileUtils.ReadFile(basePath + @"Template"+_directorySeparatorChar+"ITreeService.txt");
                //读取模板Tree——服务实现
                var treeServiceTemp = FileUtils.ReadFile(basePath + @"Template"+_directorySeparatorChar+"TreeService.txt");
                var tableList = createModel.Types==1 ? 
                    db.DbMaintenance.GetTableInfoList() : 
                    db.DbMaintenance.GetTableInfoList().Where(m=>createModel.TableNames.Contains(m.Name)).ToList();
                foreach (var row in tableList)
                {
                    var column = db.DbMaintenance.GetColumnInfosByTableName(row.Name);
                    //判断是否存在树形结构的实体，如果存在，则使用Tree模板
                    bool isParent=false,isParentList=false,isLayer=false;
                    //构建属性
                    string attrStr = "",dtoAttrStr="", tableColumn="";
                    foreach (var item in column)
                    {
                        switch (item.DbColumnName)
                        {
                            case "ParentId":
                                isParent = true;
                                break;
                            case "ParentIdList":
                                isParentList = true;
                                break;
                            case "Layer":
                                isLayer = true;
                                break;
                        }

                        if (!item.IsPrimarykey)
                        {
                            attrStr += "        /// <summary>\r\n";
                            attrStr += "        /// " + item.ColumnDescription + "\r\n";
                            attrStr += "        /// </summary>\r\n";
                            if (!item.IsNullable && item.DataType.ConvertModelType()=="string")
                            {
                                attrStr += "        [Required]\r\n";
                                attrStr += "        [StringLength("+item.Length+")]\r\n";
                            }
                            if (!item.IsNullable && item.DataType.ConvertModelType() != "string")
                            {
                                attrStr += "        [Required]\r\n";
                            }
                            attrStr += "        public " + item.DataType.ConvertModelType() + " " + item.DbColumnName + " { get; set; }" + item.DataType.ModelDefaultValue(item.DefaultValue) + "\r\n\r\n";
                        }
                        dtoAttrStr += "        /// <summary>\r\n";
                        dtoAttrStr += "        /// " + item.ColumnDescription + "\r\n";
                        dtoAttrStr += "        /// </summary>\r\n";
                        if (!item.IsNullable && item.DataType.ConvertModelType() == "string")
                        {
                            dtoAttrStr += "        [Required]\r\n";
                            dtoAttrStr += "        [StringLength(" + item.Length + ")]\r\n";
                        }
                        if (!item.IsNullable && item.DataType.ConvertModelType() != "string" && !item.IsPrimarykey)
                        {
                            dtoAttrStr += "        [Required]\r\n";
                        }
                        if (item.DataType.ConvertModelType()=="long")
                        {
                            dtoAttrStr += "        [JsonConverter(typeof(ConverterExtension), ConverterExtensionShip.UInt64)]\r\n";
                        }
                        dtoAttrStr += "        public " + item.DataType.ConvertModelType() + " " + item.DbColumnName + " { get; set; }" + item.DataType.ModelDefaultValue(item.DefaultValue) + "\r\n\r\n";
                    }
                    var modelName = row.Name.TableName();
                    tableColumn = modelTemp
                       .Replace("{NameSpace}", createModel.Namespace)
                       .Replace("{TableNameDescribe}", row.Description)
                       .Replace("{DataTable}", row.Name)
                       .Replace("{TableName}", modelName)
                       .Replace("{AttributeList}", attrStr);
                    //写入文件-Model
                    FileUtils.WriteFile(path + "/Model/"+createModel.Namespace+"/", modelName + ".cs", tableColumn);

                    var serverPath = path + "/" + createModel.Namespace + "/" + modelName + "Service/";
                    
                    //Dto
                    string dtoString = dtoTemp.Replace("{NameSpace}",createModel.Namespace)
                            .Replace("{TableNameDescribe}",row.Description.Replace("\r\n","/"))
                            .Replace("{TableName}",modelName)
                            .Replace("{AttributeList}", dtoAttrStr);
                    FileUtils.WriteFile(serverPath+"/Dto/", modelName + "Dto.cs", dtoString);

                    
                    if (!isParent && !isParentList && !isLayer)
                    {
                        //接口服务
                        string iServiceString = iserviceTemp.Replace("{NameSpace}", createModel.Namespace)
                            .Replace("{TableNameDescribe}",row.Description.Replace("\r\n","/"))
                            .Replace("{TableName}", modelName);
                        //接口实现
                        string serviceString = serviceTemp.Replace("{NameSpace}", createModel.Namespace)
                            .Replace("{TableNameDescribe}",row.Description.Replace("\r\n","/"))
                            .Replace("{Version}", createModel.ApiVersion)
                            .Replace("{TableName}", modelName);
                        FileUtils.WriteFile(serverPath, "I"+modelName + "Service.cs", iServiceString);
                        FileUtils.WriteFile(serverPath,   modelName + "Service.cs", serviceString);
                    }
                    else
                    {
                        //接口服务
                        string iTreeServiceString = iTreeServiceTemp.Replace("{NameSpace}", createModel.Namespace)
                            .Replace("{TableNameDescribe}",row.Description.Replace("\r\n","/"))
                            .Replace("{TableName}", modelName);
                        //接口实现
                        string treeServiceString = treeServiceTemp.Replace("{NameSpace}", createModel.Namespace)
                            .Replace("{TableNameDescribe}",row.Description.Replace("\r\n","/"))
                            .Replace("{Version}", createModel.ApiVersion)
                            .Replace("{TableName}", modelName);
                        FileUtils.WriteFile(serverPath, "I"+modelName + "Service.cs", iTreeServiceString);
                        FileUtils.WriteFile(serverPath,   modelName + "Service.cs", treeServiceString);
                    }
                }
                result.Data = path;
                return result;
            }
            catch (Exception ex)
            {
                return JResult<string>.Error(ex.Message);
            }
        }
    }
}